﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

using Alicanto.Helpers;
using Alicanto.Execution;
using Alicanto.Lexing;

namespace Alicanto.Compilation.Code.Blocks
{
    internal class Clazz : ICodeGenerator, IRequiresDelayedParsing
    {
        public Expression Code { get; private set; }

        public Clazz()
        {
            this.Code = Expression.Empty();
        }

        public IEnumerable<ParseInstruction> Generate(TokenSequence tokens, Scope scope)
        {
            // Class name
            string name = tokens.Pop(TokenType.SimpleName).Str;

            EnterScope enterContext = new EnterScope();
            yield return enterContext;
            enterContext.Scope.AsExecutionContext(name, ScopeType.Class);

            // Class body
            // Will be parsed as any other code block
            Parse body = new Parse();
            yield return body;

            yield return new LeaveScope();
            scope.ExecutionContext[name] = new ExecutionContextMember(enterContext.Scope.ExecutionContext);
        }

        public TokenSequence SkipTokens(TokenSequence tokens)
        {
            TokenSequence skipped = new TokenSequence();

            int open = 1;
            while (tokens.Available > 0 && open > 0)
            {
                Token token = tokens.Pop();
                skipped.Push(token);

                if (token.Type == TokenType.Block)
                    open++;
                else if (token.Type == TokenType.End)
                    open--;
            }

            if (open > 0)
                throw new Exception();

            return skipped;
        }
    }
}
